package net.wanglu.www.zzz.rule.sva;

import java.util.HashMap;
import java.util.regex.Pattern;

import net.wanglu.www.zzz.rule.BadEgg;
import net.wanglu.www.zzz.rule.Rule;
import net.wanglu.www.zzz.service.se.nsubj._NSubjTuple;
import edu.stanford.nlp.trees.TreeGraphNode;

public class UncountableNounAsSubj extends _SvaRule {

	public static final Pattern MaterialNoun = Pattern.compile("\\bbread\\b|\\bbeer\\b|\\bcloth\\b|\\bcoffee\\b|\\bcream\\b|\\bdust\\b|\\bgin\\b|\\bglass\\b|\\bgold\\b|\\bice\\b|\\bjam\\b|\\boil\\b|\\bpaper\\b|\\bsand\\b|\\bsoap\\b|\\bstone\\b|\\btea\\b|\\bwater\\b|\\bwine\\b|\\bwood\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern AbstractNoun = Pattern.compile("\\badvice\\b|\\bbeauty\\b|\\bcourage\\b|\\bdeath\\b|\\bexperience\\b|\\bfear\\b|\\bhelp\\b|\\bhope\\b|\\bhorror\\b|\\binformation\\b|\\bknowledge\\b|\\bmercy\\b|\\bpity\\b|\\brelief\\b|\\bsuspicion\\b|\\bwork\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern OtherUncountableNoun = Pattern.compile("\\bbaggage\\b|\\bcamping\\b|\\bdamage\\b|\\bfurniture\\b|\\bluggage\\b|\\bparking\\b|\\bshopping\\b|\\bweather\\b|\\bhair\\b|\\binformation\\b|\\bknowledge\\b|\\bnews\\b|\\brubbish\\b", Pattern.CASE_INSENSITIVE);
		
	public final int LocativeGenitiveFlag = 1;
	
	@Override
	public Object applicable(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		if ( super.applicable(objects) == Rule.Inapplicable) return Rule.Inapplicable;
		_NSubjTuple nst = (_NSubjTuple) objects[1];
		if ( !"NP".equals(nst.getSubjectAncestor().value())) return Rule.Inapplicable;
		return Rule.Applicable;
	}

	@Override
	public Object deviseRightSolution(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return super.deviseRightSolution(objects);
	}

	@Override
	public Object examine(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		HashMap<?, ?> preprocessData = (HashMap<?, ?>) objects[0];
		_NSubjTuple nst =  (_NSubjTuple) objects[1];
		
		if ( this.applicable(preprocessData, nst) == Rule.Inapplicable) return Rule.Inapplicable;
		TreeGraphNode subj = (TreeGraphNode) nst.getSubj();
		TreeGraphNode verb = (TreeGraphNode) nst.getVerb();
		TreeGraphNode cop = (TreeGraphNode) nst.getCop();
		TreeGraphNode closestAux = (TreeGraphNode) nst.getAux();
		
		TreeGraphNode pred = verb;
		if ( cop != null) pred = cop;
		if ( closestAux != null) pred = closestAux;
		String predWord = pred.label().word();
		String predTag = pred.label().tag();

		if ( MaterialNoun.matcher(subj.label().word()).find() || AbstractNoun.matcher(subj.label().word()).find() || OtherUncountableNoun.matcher(subj.label().word()).find()) {
			if (Rule.SingularVerb.matcher(predTag).find() && !"were".equals(predWord)) {
				return null;
			} else {
				BadEgg egg = new BadEgg();
				egg.setFlag(this.LocativeGenitiveFlag);
				egg.setProperty(BadEgg.Error);
				egg.setViolatedRule(this);
				egg.whereIsWrong = nst;
				return egg;
			}							
		}
		return Rule.Inapplicable;
	}

	@Override
	public Object whyItsWrong(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		sb.clear();
		sb.append("<p>");
		sb.append("不可数的抽象名词、物质名词作主语时，要采用单数形式的谓语动词。");
		sb.append("</p>");
		return sb.toString();
	}
}
